import { Action } from '@ngrx/store';
import { Project, User } from '../domain/index';

/**
 * For each action type in an action group, make a simple
 * enum object for all of this group's action types.
 */
export enum ProjectActionTypes {
    ADD = '[Project] Add',
    ADD_SUCCESS = '[Project] Add Success',
    ADD_FAIL = '[Project] Add Fail',
    UPDATE = '[Project] Update',
    UPDATE_SUCCESS = '[Project] Update Success',
    UPDATE_FAIL = '[Project] Update Fail',
    DELETE = '[Project] Delete',
    DELETE_SUCCESS = '[Project] Delete Success',
    DELETE_FAIL = '[Project] Delete Fail',
    LOAD = '[Project] Load',
    LOAD_SUCCESS = '[Project] Load Success',
    LOAD_FAIL = '[Project] Load Fail',
    INVITE = '[Project] Invite',
    INVITE_SUCCESS = '[Project] Invite Success',
    INVITE_FAILE = '[Project] Invite Fail',
    SELECT_PROJECT = '[Project] Select Project'
}

/**
 * Every action is comprised of at least a type and an optional
 * payload. Expressing actions as classes enables powerful
 * type checking in reducer functions.
 */
export class ProjectAddAction implements Action {
    readonly type = ProjectActionTypes.ADD;
    constructor(public payload: Project) { }
}

export class ProjectAddSuccessAction implements Action {
    readonly type = ProjectActionTypes.ADD_SUCCESS;
    constructor(public payload: Project) { }
}
export class ProjectAddFailAction implements Action {
    readonly type = ProjectActionTypes.ADD_FAIL;
    constructor(public payload: string) { }
}

export class ProjectUpdateAction implements Action {
    readonly type = ProjectActionTypes.UPDATE;
    constructor(public payload: Project) { }
}

export class ProjectUpdateSuccessAction implements Action {
    readonly type = ProjectActionTypes.UPDATE_SUCCESS;
    constructor(public payload: Project) { }
}
export class ProjectUpdateFailAction implements Action {
    readonly type = ProjectActionTypes.UPDATE_FAIL;
    constructor(public payload: string) { }
}

export class ProjectDeleteAction implements Action {
    readonly type = ProjectActionTypes.DELETE;
    constructor(public payload: Project) { }
}

export class ProjectDeleteSuccessAction implements Action {
    readonly type = ProjectActionTypes.DELETE_SUCCESS;
    constructor(public payload: Project) { }
}

export class ProjectDeleteFailAction implements Action {
    readonly type = ProjectActionTypes.DELETE_FAIL;
    constructor(public payload: string) { }
}

export class ProjectLoadAction implements Action {
    readonly type = ProjectActionTypes.LOAD;
    constructor(public payload: any) { }
}

export class ProjectLoadSuccessAction implements Action {
    readonly type = ProjectActionTypes.LOAD_SUCCESS;
    constructor(public payload: Project[]) { }
}
export class ProjectLoadFailAction implements Action {
    readonly type = ProjectActionTypes.LOAD_FAIL;
    constructor(public payload: string) { }
}
export class ProjectInviteAction implements Action {
    readonly type = ProjectActionTypes.INVITE;
    constructor(public payload: { projectId: string; members: User[] }) { }
}

export class ProjectInviteSuccessAction implements Action {
    readonly type = ProjectActionTypes.INVITE_SUCCESS;
    constructor(public payload: Project) { }
}
export class ProjectInviteFailAction implements Action {
    readonly type = ProjectActionTypes.INVITE_FAILE;
    constructor(public payload: string) { }
}
export class ProjectSelectAction implements Action {
    readonly type = ProjectActionTypes.SELECT_PROJECT;
    constructor(public payload: Project) { }
}
/**
 * Export a type alias of all actions in this action group
 * so that reducers can easily compose action types
 */
export type ProjectActions
    = ProjectAddAction
    | ProjectAddSuccessAction
    | ProjectAddFailAction
    | ProjectUpdateAction
    | ProjectUpdateSuccessAction
    | ProjectUpdateFailAction
    | ProjectDeleteAction
    | ProjectDeleteSuccessAction
    | ProjectDeleteFailAction
    | ProjectLoadAction
    | ProjectLoadSuccessAction
    | ProjectLoadFailAction
    | ProjectInviteAction
    | ProjectInviteSuccessAction
    | ProjectInviteFailAction
    | ProjectSelectAction;
